# https://stackoverflow.com/questions/51893313/adjust-the-size-width-height-of-a-custom-qtablewidget
import os

import logzero
from PyQt5.QtCore import QRegExp, Qt, QTimer
from PyQt5.QtGui import QColor, QIcon, QRegExpValidator
from PyQt5.QtWidgets import (
    QAbstractScrollArea,
    QDialog,
    QFileDialog,
    QGridLayout,
    QGroupBox,
    QHBoxLayout,
    QLabel,
    QLineEdit,
    QPushButton,
    QSizePolicy,
    QSplitter,
    QTableWidget,
    QTableWidgetItem,
    QTextEdit,
    QVBoxLayout,
    QWidget,
)

import mengy_spac800
import mengy_spac800_bt
from helpers.mengy_bytes_helper import bytes2Int
from helpers.mengy_doc_generate import generateDocByTemplate

VAIN_DATA = "_" * 12


class ReportBrowser(QDialog):
    spac800_module = mengy_spac800

    def __init__(self, parent, serRecvDir, sendQueuePack, logger=logzero.logger):
        super().__init__(parent)
        self.papa = parent
        self.logger = logger
        self.initUI()
        self.serRecvDir = serRecvDir
        self.sendQueuePack = sendQueuePack
        self.lastOutputFileDir = "./"

    def initUI(self):
        wdgt = QSplitter(Qt.Vertical, self)
        meaOutSpliter = QSplitter(Qt.Horizontal)
        self.createPrtDataGroupBox()
        self.createMeaDataGroupBox()
        self.createSNEditor()
        self.createOututGroupBox()

        wdgt.addWidget(self.prtDataGroupBox)
        meaOutSpliter.addWidget(self.meaDataGroupBox)
        meaOutSpliter.addWidget(self.outputGroupBox)
        wdgt.addWidget(meaOutSpliter)

        self.setWindowTitle("测试数据查看")
        self.setWindowIcon(QIcon("./icons/icons8-search-960.png"))
        # self.setGeometry(300, 300, 820, 620)
        self.resize(820, 560)
        # for tw in self.prtTWs + self.meaTWs:
        #     tw.resizeColumnsToContents()
        #     # tw.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        #     tw.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
        #     tw.setEditTriggers(QTableWidget.NoEditTriggers)

    def createPrtDataGroupBox(self):
        self.prtDataGroupBox = QGroupBox("保护测量")
        layout = QHBoxLayout(self.prtDataGroupBox)
        tableConf = self.spac800_module.REPORT_PRT_TABLE_CONF
        self.prtTW = QTableWidget(len(tableConf.rowNames), len(tableConf.columnNames))
        self.prtTW.setHorizontalHeaderLabels(tableConf.columnNames)
        self.prtTW.setVerticalHeaderLabels(tableConf.rowNames)
        self.prtTW.setEditTriggers(QTableWidget.NoEditTriggers)
        for i in range(self.prtTW.rowCount()):
            for j in range(self.prtTW.columnCount()):
                it = QTableWidgetItem(VAIN_DATA)
                it.setTextAlignment(Qt.AlignCenter)
                self.prtTW.setItem(i, j, it)

        self.prtTW.resizeColumnsToContents()
        self.prtTW.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
        self.prtTW.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        layout.addWidget(self.prtTW)

    def createMeaDataGroupBox(self):
        self.meaTWs = []
        self.meaDataGroupBox = QGroupBox("计量测量")
        layout = QHBoxLayout(self.meaDataGroupBox)
        spliterV = QSplitter(Qt.Vertical)
        spliterH = QSplitter(Qt.Horizontal)
        meaGBs = []
        for idx, conf in enumerate(mengy_spac800.REPORT_MEA_TABLE_CONFS):
            subGB = QGroupBox(("相电流", "相电压", "功率")[idx])
            subLayout = QGridLayout(subGB)

            tw = QTableWidget(len(conf.rowNames), len(conf.columnNames))
            tw.setHorizontalHeaderLabels(conf.columnNames)
            tw.setVerticalHeaderLabels(conf.rowNames)

            for i in range(tw.rowCount()):
                for j in range(tw.columnCount()):
                    it = QTableWidgetItem(VAIN_DATA)
                    it.setTextAlignment(Qt.AlignCenter)
                    tw.setItem(i, j, it)
            tw.resizeColumnsToContents()
            tw.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
            tw.setEditTriggers(QTableWidget.NoEditTriggers)
            tw.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
            self.meaTWs.append(tw)
            subLayout.addWidget(tw, 0, 0)
            meaGBs.append(subGB)
        spliterH.addWidget(meaGBs[0])
        spliterH.addWidget(meaGBs[1])
        spliterV.addWidget(spliterH)
        spliterV.addWidget(meaGBs[2])
        layout.addWidget(spliterV)

    def updateData(self):
        self.updatePrtData()
        self.updateMeaData()

    def updatePrtData(self):
        for conf in self.spac800_module.REPORT_PRT_TABLE_ITEM_CONF:
            it = self.prtTW.item(conf.row, conf.column)
            if it is None:
                continue
            value = self.papa.reportPrtData.get(conf.keyName)
            if value is None:
                it.setText(conf.keyName)
            else:
                data, text = value
                it.setText(text.strip())
                if conf.manten * conf.goukaku[0] <= data <= conf.manten * conf.goukaku[1]:
                    it.setBackground(QColor("#00FF00"))
                else:
                    it.setBackground(QColor("#FF0000"))

    def updateMeaData(self):
        for idx, itemConfs in enumerate(mengy_spac800.REPORT_MEA_TABLE_ITEM_CONFS):
            tw = self.meaTWs[idx]
            for conf in itemConfs:
                it = tw.item(conf.row, conf.column)
                if it is None:
                    continue
                value = self.papa.reportMeaData.get(conf.keyName)
                if value is None:
                    it.setText(conf.keyName)
                else:
                    data, text = value
                    it.setText(text.strip())
                    if conf.manten * conf.goukaku[0] <= data <= conf.manten * conf.goukaku[1]:
                        it.setBackground(QColor("#00FF00"))
                    else:
                        it.setBackground(QColor("#FF0000"))

    def createOututGroupBox(self):
        self.outputGroupBox = QGroupBox("数据输出")
        layout = QVBoxLayout(self.outputGroupBox)
        self.outputTempPathBtn = QPushButton("模板选择")
        self.outputTempPathBtn.clicked.connect(self.outputSelectPath)
        self.outputTempPathLdt = QLineEdit()
        self.outputResultPathBtn = QPushButton("输出路径选择")
        self.outputResultPathBtn.clicked.connect(self.outputSelectPath)
        self.outputResultPathLdt = QLineEdit()
        self.outputReultInfo = QTextEdit()
        self.outputReultInfo.setReadOnly(True)
        self.outputReultInfo.setMaximumHeight(120)
        self.outputDoBtn = QPushButton("输出")
        self.outputDoBtn.clicked.connect(self.outputDeal)
        layout.addWidget(self.outputTempPathBtn)
        layout.addWidget(self.outputTempPathLdt)
        layout.addWidget(self.outputResultPathBtn)
        layout.addWidget(self.outputResultPathLdt)
        snLayout = QHBoxLayout()
        snLayout.addWidget(QLabel("出厂编码"))
        self.readSNBtn = QPushButton("读取")
        self.writeSNBtn = QPushButton("写入")
        self.readSNBtn.clicked.connect(self.dealSNButton)
        self.writeSNBtn.clicked.connect(self.dealSNButton)
        snLayout.addWidget(self.readSNBtn)
        snLayout.addWidget(self.writeSNBtn)
        layout.addLayout(snLayout)
        layout.addWidget(self.snEditor)
        layout.addWidget(QLabel("输出结果"))
        layout.addWidget(self.outputReultInfo)
        layout.addWidget(self.outputDoBtn)

    def dealReadSN(self):
        if any((key not in self.serRecvDir.keys() for key in range(0x0700, 0x0704 + 1))):
            return
        values = [bytes2Int(self.serRecvDir.get(0x0700 + i)) for i in range(5)]
        self.logger.info("dealReadSN product values is {}".format(values))
        snNum = 0
        for i in values[1:4]:
            snNum = (snNum * 10 ** 4) + i
        self.snBatch.setText("{:02d}".format(values[0]))
        self.snNum.setText("{:012d}".format(snNum))

    def dealWriteSN(self):
        self.logger.info("dealWriteSN")
        data = []
        data.append(int(self.snBatch.text()))
        sn = int(self.snNum.text())
        data.append(sn // 10 ** 8)
        data.append(sn // 10 ** 4 % 10 ** 4)
        data.append(sn % 10 ** 4)
        self.sendQueuePack(funCode=0x10, start=0x0700, data=data)
        QTimer.singleShot(2000, self.dealReadSN)

    def dealSNButton(self):
        sender = self.sender()
        if sender is self.readSNBtn:
            self.dealReadSN()
        elif sender is self.writeSNBtn:
            self.dealWriteSN()

    def createSNEditor(self):
        self.snEditor = QWidget()
        layout = QHBoxLayout(self.snEditor)
        layout.setContentsMargins(0, 0, 0, 0)
        self.snCustomize = QLineEdit()
        self.snCustomize.setMaxLength(15)
        self.snCustomize.setFixedWidth(92)
        layout.addWidget(self.snCustomize)
        layout.addWidget(QLabel("-"))
        self.snBatch = QLineEdit()
        self.snBatch.setValidator(QRegExpValidator(QRegExp(r"\d\d")))
        self.snBatch.setMaxLength(2)
        self.snBatch.setFixedWidth(24)
        layout.addWidget(self.snBatch)
        layout.addWidget(QLabel("-"))
        self.snNum = QLineEdit()
        self.snNum.setValidator(QRegExpValidator(QRegExp(r"\d{0,12}")))
        self.snNum.setMaxLength(12)
        self.snNum.setFixedWidth(88)
        layout.addWidget(self.snNum)

    def outputSelectPath(self):
        """
        filter usage example:
        https://gis.stackexchange.com/questions/260022/how-to-add-a-filter-to-qfiledialog-getopenfilename
        """
        sender = self.sender()
        if sender is self.outputTempPathBtn:
            fd = QFileDialog()
            filt = "Word 文档 (*.docx)"
            filename, _ = fd.getOpenFileName(filter=filt)
            if filename:
                self.outputTempPathLdt.setText(filename)
        elif sender is self.outputResultPathBtn:
            fd = QFileDialog()
            filt = "Word 文档 (*.docx)"
            self.dealReadSN()
            docName = "SPAC800出厂检验记录-{}-{}-{}.docx".format(
                self.snCustomize.text(), self.snBatch.text(), self.snNum.text()
            )
            filename, _ = fd.getSaveFileName(filter=filt, directory=os.path.join(self.lastOutputFileDir, docName))
            if filename:
                self.lastOutputFileDir = os.path.split(filename)[0]
                self.outputResultPathLdt.setText(filename)

    def outputDeal(self):
        data = self.papa.reportPrtData.copy()
        data.update(self.papa.reportMeaData)
        templatePath = self.outputTempPathLdt.text()
        outputPath = self.outputResultPathLdt.text()
        for key in data.keys():
            data[key] = data[key][1]
        result = generateDocByTemplate(data, templatePath, outputPath, self.logger)
        if result is True:
            info = "{} -- {} 输出成功".format(templatePath, outputPath)
        else:
            info = "{} -- {} 输出失败".format(templatePath, outputPath)
        self.outputReultInfo.append(info)


class ReportBrowser_BT(ReportBrowser):
    spac800_module = mengy_spac800_bt
    pass
